package utils

import (
	"bytes"
	"compress/gzip"
	"crypto/md5"
	"cubeAdmin/controllers"
	"encoding/hex"
	"fmt"
	"github.com/beego/beego/v2/core/logs"
	"golang.org/x/crypto/bcrypt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"reflect"
	"strings"
)

// 加密
func HashAndSalt(pwd []byte) string {
	hash, err := bcrypt.GenerateFromPassword(pwd, bcrypt.MinCost)
	if err != nil {
		controllers.ErrMsg(err.Error())
	}
	return string(hash)
}

// 密码验证
func ComparePwd(hashPwd string, plainPwd []byte) bool {
	logs.Info(hashPwd)
	byteHash := []byte(hashPwd)
	err := bcrypt.CompareHashAndPassword(byteHash, plainPwd)
	if err != nil {
		logs.Error(err.Error())
		return false
	}

	return true
}

// 判断array contain item
func Contains(array interface{}, val interface{}) (index int) {
	index = -1
	switch reflect.TypeOf(array).Kind() {
	case reflect.Slice:
		{
			s := reflect.ValueOf(array)
			for i := 0; i < s.Len(); i++ {
				if reflect.DeepEqual(val, s.Index(i).Interface()) {
					index = i
					return
				}
			}
		}
	}
	return
}

// [a] -> a -> a
// [a b c] -> a b c -> a,b,c
func Convert(array interface{}) string {
	return strings.Replace(strings.Trim(fmt.Sprint(array), "[]"), " ", ",", -1)
}

func IntToBool(num int8) bool {
	if num > 0 {
		return true
	}
	return false
}

func ReturnQ(length int) string {
	var str string
	for i := 0; i < length; i++ {
		str += ",?"
	}
	return str[1:]
}

// 绝对路径，abs => absolute
func ObjectAbs(object string) string {
	return "/" + strings.TrimLeft(object, " ./")
}

// 相对路径 rel => relative
func ObjectRel(object string) string {
	return strings.TrimLeft(object, " ./")
}

// GetRemote 获取图片文件流
func GetRemote(url string) ([]byte, error) {
	res, err := http.Get(url)
	if err != nil {
		return nil, err
	}

	defer func(Body io.ReadCloser) {
		_ = Body.Close()
	}(res.Body)

	bytes, err := ioutil.ReadAll(res.Body)

	if err != nil {
		return nil, err
	}
	return bytes, err
}

// MD5Crypt MD5 Crypt
func MD5Crypt(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}

// CompressByGzip 压缩成 gzip
func CompressByGzip(tmpFile, saveFile string) (err error) {
	var (
		input []byte
		buf   bytes.Buffer
	)
	input, err = ioutil.ReadFile(tmpFile)
	if err != nil {
		return
	}

	writer, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
	defer func(writer *gzip.Writer) {
		err := writer.Close()
		if err != nil {
			logs.Error(err.Error())
		}
	}(writer)

	writer.Write(input)
	writer.Flush()

	err = ioutil.WriteFile(saveFile, buf.Bytes(), os.ModePerm)

	return
}
